package com.yeban.javase.day12.test.streamtest;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Desc TODO
 * @Author yeban
 * @Date 2025/10/22
 *
 * 1.练习Stream中的常用方法of()、iterate()、generate()、findFirst()、findAny()、anyMatch()、distinct()等
 */
public class StreamTest01 {

    public static void main(String[] args) {

        // of()：快速创建一个包含指定元素的流
        System.out.println("---------- of() ----------");
        String result = Stream.of(3,1,5,2,8,6,10,4,7,9).filter(s -> s > 5).sorted().map(String::valueOf).collect(Collectors.joining(" "));
        System.out.println(result);


        // iterate()：通过迭代方式创建无限流，生成元素     静态方法
        System.out.println("---------- iterate() ----------");
        // 生成前5个偶数
        Stream.iterate(0, n -> n + 2).limit(5).forEach(System.out::println);


        // generate()：创建无限流，Supplier 函数生成元素，且元素之间没有依赖关系   静态方法
        System.out.println("---------- generate() ----------");
        // 生成固定常量
        Stream.generate(() -> "hello").limit(5).forEach(System.out::println);
        // 生成随机数
        Stream.generate(() -> (int)(Math.random()*10 + 1)).limit(5).forEach(System.out::println);
        // 生成自定义对象
        Stream.generate(User::new).limit(3).forEach(System.out::println);


        // findFirst()：获取流中的第一个元素，返回值是Optional类型
        System.out.println("---------- findFirst() ----------");
        // isPresent()：是Optional类中的方法，判断 Optional 对象中是否包含实际的值
        Stream.of("aab", "abc", "bac", "ade").findFirst().ifPresent(System.out::println);


        // findAny()：从流中获取任意一个元素，返回值为 Optional<T> 类型（避免空指针异常）
        System.out.println("---------- findAny() ----------");
        // 在串行流中（默认的流是串行的），元素是按顺序依次处理的，findAny() 会直接返回第一个遇到的元素（和 findFirst() 表现一致）
        Stream.of("aab", "abc", "bac", "ade").findAny().ifPresent(System.out::println);
        // 在并行流中使用 findAny()，结果可能不确定
        Stream<String> stream = Stream.of("aab", "abc", "bac", "ade").parallel();   // 普通流调用 parallel() 开启并行
        stream.findAny().ifPresent(System.out::println);


        // anyMatch()：判断流中是否存在至少一个元素满足指定的条件
        // 终止流  返回boolean类型
        // 集合中是否有存在奇数
        System.out.println("---------- anyMatch() ----------");
        boolean b = Stream.of(2,4,6,7,8,9,10).anyMatch(s -> s % 2 != 0);
        System.out.println(b);
        // 判断列表中是否包含空字符串
        List<String> words = Arrays.asList("apple", "", "banana", "cherry");
        boolean b1 = words.stream().anyMatch(s -> s.isEmpty());
        System.out.println(b1);


        // distinct()：去除流中重复的元素，去重逻辑基于元素的 equals()
        System.out.println("---------- anyMatch() ----------");
        // 去除String中的重复元素
        Stream.of("aaa" , "bbb" , "ccc" , "ddd", "aaa").distinct().forEach(System.out::println);
        // 去除User中的重复元素
        Stream.of(new User("张三",18), new User("李四",19), new User("张三",19), new User("张三",18))
                .distinct().forEach(System.out::println);
    }
}

class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age && Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "User{name = " + name + ", age = " + age + "}";
    }
}
